/*
 * winioctl.h
 *
 * 32-Bit Windows Device I/O control codes.
 * Definitions extracted from various NT DDK headers.
 *
 * This file is part of the w32api package.
 *
 * Contributors:
 *   Created by Casper S. Hornstrup <chorns@users.sourceforge.net>
 *   Amine Khaldi <amine.khaldi@reactos.org>
 *   Pierre Schweitzer <pierre@reactos.org>
 *   Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
 *
 * THIS SOFTWARE IS NOT COPYRIGHTED
 *
 * This source code is offered for use in the public domain. You may
 * use, modify or distribute it freely.
 *
 * This code is distributed in the hope that it will be useful but
 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
 * DISCLAIMED. This includes but is not limited to warranties of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

#ifndef _WINIOCTL_
#define _WINIOCTL_

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4201)
#pragma warning(disable:4820)
#endif


#ifndef _DEVIOCTL_
#define _DEVIOCTL_

#define DEVICE_TYPE DWORD

#define FILE_DEVICE_BEEP              1
#define FILE_DEVICE_CD_ROM            2
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 3
#define FILE_DEVICE_CONTROLLER        4
#define FILE_DEVICE_DATALINK          5
#define FILE_DEVICE_DFS               6
#define FILE_DEVICE_DISK              7
#define FILE_DEVICE_DISK_FILE_SYSTEM  8
#define FILE_DEVICE_FILE_SYSTEM       9
#define FILE_DEVICE_INPORT_PORT       10
#define FILE_DEVICE_KEYBOARD          11
#define FILE_DEVICE_MAILSLOT          12
#define FILE_DEVICE_MIDI_IN           13
#define FILE_DEVICE_MIDI_OUT          14
#define FILE_DEVICE_MOUSE             15
#define FILE_DEVICE_MULTI_UNC_PROVIDER 16
#define FILE_DEVICE_NAMED_PIPE        17
#define FILE_DEVICE_NETWORK           18
#define FILE_DEVICE_NETWORK_BROWSER   19
#define FILE_DEVICE_NETWORK_FILE_SYSTEM 20
#define FILE_DEVICE_NULL              21
#define FILE_DEVICE_PARALLEL_PORT     22
#define FILE_DEVICE_PHYSICAL_NETCARD  23
#define FILE_DEVICE_PRINTER           24
#define FILE_DEVICE_SCANNER           25
#define FILE_DEVICE_SERIAL_MOUSE_PORT 26
#define FILE_DEVICE_SERIAL_PORT       27
#define FILE_DEVICE_SCREEN            28
#define FILE_DEVICE_SOUND             29
#define FILE_DEVICE_STREAMS           30
#define FILE_DEVICE_TAPE              31
#define FILE_DEVICE_TAPE_FILE_SYSTEM  32
#define FILE_DEVICE_TRANSPORT         33
#define FILE_DEVICE_UNKNOWN           34
#define FILE_DEVICE_VIDEO             35
#define FILE_DEVICE_VIRTUAL_DISK      36
#define FILE_DEVICE_WAVE_IN           37
#define FILE_DEVICE_WAVE_OUT          38
#define FILE_DEVICE_8042_PORT         39
#define FILE_DEVICE_NETWORK_REDIRECTOR 40
#define FILE_DEVICE_BATTERY           41
#define FILE_DEVICE_BUS_EXTENDER      42
#define FILE_DEVICE_MODEM             43
#define FILE_DEVICE_VDM               44
#define FILE_DEVICE_MASS_STORAGE      45
#define FILE_DEVICE_SMB               46
#define FILE_DEVICE_KS                47
#define FILE_DEVICE_CHANGER           48
#define FILE_DEVICE_SMARTCARD         49
#define FILE_DEVICE_ACPI              50
#define FILE_DEVICE_DVD               51
#define FILE_DEVICE_FULLSCREEN_VIDEO  52
#define FILE_DEVICE_DFS_FILE_SYSTEM   53
#define FILE_DEVICE_DFS_VOLUME        54
#define FILE_DEVICE_SERENUM           55
#define FILE_DEVICE_TERMSRV           56
#define FILE_DEVICE_KSEC              57
#define FILE_DEVICE_FIPS              58
#define FILE_DEVICE_INFINIBAND        59
#define FILE_DEVICE_VMBUS             62
#define FILE_DEVICE_CRYPT_PROVIDER    63
#define FILE_DEVICE_WPD               64
#define FILE_DEVICE_BLUETOOTH         65
#define FILE_DEVICE_MT_COMPOSITE      66
#define FILE_DEVICE_MT_TRANSPORT      67
#define FILE_DEVICE_BIOMETRIC         68
#define FILE_DEVICE_PMI               69
#define FILE_DEVICE_EHSTOR            70
#define FILE_DEVICE_DEVAPI            71
#define FILE_DEVICE_GPIO              72
#define FILE_DEVICE_USBEX             73
#define FILE_DEVICE_CONSOLE           80
#define FILE_DEVICE_NFP               81
#define FILE_DEVICE_SYSENV            82
#define FILE_DEVICE_VIRTUAL_BLOCK     83
#define FILE_DEVICE_POINT_OF_SERVICE  84
#define FILE_DEVICE_STORAGE_REPLICATION 85
#define FILE_DEVICE_TRUST_ENV         86
#define FILE_DEVICE_UCM               87
#define FILE_DEVICE_UCMTCPCI          88
#define FILE_DEVICE_PERSISTENT_MEMORY 89
#define FILE_DEVICE_NVDIMM            90
#define FILE_DEVICE_HOLOGRAPHIC       91
#define FILE_DEVICE_SDFXHCI           92
#define FILE_DEVICE_UCMUCSI           93

/*  Also in ddk/winddk.h */
#define FILE_ANY_ACCESS        0x00000000
#define FILE_SPECIAL_ACCESS    FILE_ANY_ACCESS
#define FILE_READ_ACCESS       0x00000001
#define FILE_WRITE_ACCESS      0x00000002

#define METHOD_BUFFERED               0
#define METHOD_IN_DIRECT              1
#define METHOD_OUT_DIRECT             2
#define METHOD_NEITHER                3

#define CTL_CODE(t,f,m,a)                (((t)<<16)|((a)<<14)|((f)<<2)|(m))
#define DEVICE_TYPE_FROM_CTL_CODE(c)     (((DWORD)((c)&0xffff0000))>>16)

#endif /* _DEVIOCTL_ */

#ifndef _NTDDSTOR_H_
// #define _NTDDSTOR_H_

#define IOCTL_STORAGE_BASE               FILE_DEVICE_MASS_STORAGE
#define IOCTL_STORAGE_CHECK_VERIFY       CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_CHECK_VERIFY2      CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STORAGE_MEDIA_REMOVAL      CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_EJECT_MEDIA        CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_LOAD_MEDIA         CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_LOAD_MEDIA2        CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STORAGE_RESERVE            CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_RELEASE            CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_FIND_NEW_DEVICES   CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_EJECTION_CONTROL   CTL_CODE(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STORAGE_MCN_CONTROL        CTL_CODE(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STORAGE_GET_MEDIA_TYPES    CTL_CODE(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX CTL_CODE(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STORAGE_RESET_BUS          CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_RESET_DEVICE       CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_STORAGE_GET_DEVICE_NUMBER  CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_STORAGE_PREDICT_FAILURE    CTL_CODE(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _PREVENT_MEDIA_REMOVAL {
  BOOLEAN PreventMediaRemoval;
} PREVENT_MEDIA_REMOVAL, *PPREVENT_MEDIA_REMOVAL;

#endif /* _NTDDSTOR_H_ */

#ifndef _NTDDDISK_H_
// #define _NTDDDISK_H_

#define IOCTL_DISK_BASE                  FILE_DEVICE_DISK
#define IOCTL_DISK_GET_DRIVE_GEOMETRY    CTL_CODE(IOCTL_DISK_BASE,0,METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_GET_PARTITION_INFO    CTL_CODE(IOCTL_DISK_BASE,1,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_SET_PARTITION_INFO    CTL_CODE(IOCTL_DISK_BASE,2,METHOD_BUFFERED,FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#define IOCTL_DISK_GET_DRIVE_LAYOUT      CTL_CODE(IOCTL_DISK_BASE,3,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_SET_DRIVE_LAYOUT      CTL_CODE(IOCTL_DISK_BASE,4,METHOD_BUFFERED,FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#define IOCTL_DISK_VERIFY                CTL_CODE(IOCTL_DISK_BASE,5,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_FORMAT_TRACKS         CTL_CODE(IOCTL_DISK_BASE,6,METHOD_BUFFERED,FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#define IOCTL_DISK_REASSIGN_BLOCKS       CTL_CODE(IOCTL_DISK_BASE,7,METHOD_BUFFERED,FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#define IOCTL_DISK_PERFORMANCE           CTL_CODE(IOCTL_DISK_BASE,8,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_IS_WRITABLE           CTL_CODE(IOCTL_DISK_BASE,9,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_LOGGING               CTL_CODE(IOCTL_DISK_BASE,10,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_FORMAT_TRACKS_EX      CTL_CODE(IOCTL_DISK_BASE,11,METHOD_BUFFERED,FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#define IOCTL_DISK_HISTOGRAM_STRUCTURE   CTL_CODE(IOCTL_DISK_BASE,12,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_HISTOGRAM_DATA        CTL_CODE(IOCTL_DISK_BASE,13,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_HISTOGRAM_RESET       CTL_CODE(IOCTL_DISK_BASE,14,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_REQUEST_STRUCTURE     CTL_CODE(IOCTL_DISK_BASE,15,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_REQUEST_DATA          CTL_CODE(IOCTL_DISK_BASE,16,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_GET_PARTITION_INFO_EX CTL_CODE(IOCTL_DISK_BASE,0x12,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_SET_PARTITION_INFO_EX CTL_CODE(IOCTL_DISK_BASE,0x13,METHOD_BUFFERED,FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX   CTL_CODE(IOCTL_DISK_BASE,0x14,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_SET_DRIVE_LAYOUT_EX   CTL_CODE(IOCTL_DISK_BASE,0x15,METHOD_BUFFERED,FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_CREATE_DISK           CTL_CODE(IOCTL_DISK_BASE,0x16,METHOD_BUFFERED,FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_GET_LENGTH_INFO       CTL_CODE(IOCTL_DISK_BASE,0x17,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_PERFORMANCE_OFF       CTL_CODE(IOCTL_DISK_BASE,0x18,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE,0x28,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_GROW_PARTITION        CTL_CODE(IOCTL_DISK_BASE,0x34,METHOD_BUFFERED,FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_GET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE,0x35,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_SET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE,0x36,METHOD_BUFFERED,FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_DELETE_DRIVE_LAYOUT   CTL_CODE(IOCTL_DISK_BASE,0x40,METHOD_BUFFERED,FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_UPDATE_PROPERTIES CTL_CODE(IOCTL_DISK_BASE,0x50,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_CHECK_VERIFY      CTL_CODE(IOCTL_DISK_BASE,0x200,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_MEDIA_REMOVAL     CTL_CODE(IOCTL_DISK_BASE,0x201,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_EJECT_MEDIA       CTL_CODE(IOCTL_DISK_BASE,0x202,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_LOAD_MEDIA        CTL_CODE(IOCTL_DISK_BASE,0x203,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_RESERVE           CTL_CODE(IOCTL_DISK_BASE,0x204,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_RELEASE           CTL_CODE(IOCTL_DISK_BASE,0x205,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_FIND_NEW_DEVICES  CTL_CODE(IOCTL_DISK_BASE,0x206,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_REMOVE_DEVICE     CTL_CODE(IOCTL_DISK_BASE,0x207,METHOD_BUFFERED,FILE_READ_ACCESS)
#define IOCTL_DISK_GET_MEDIA_TYPES   CTL_CODE(IOCTL_DISK_BASE,0x300,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISK_UPDATE_DRIVE_SIZE CTL_CODE(IOCTL_DISK_BASE, 0x0032, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)


#define PARTITION_ENTRY_UNUSED          0x00
#define PARTITION_FAT_12                0x01
#define PARTITION_XENIX_1               0x02
#define PARTITION_XENIX_2               0x03
#define PARTITION_FAT_16                0x04
#define PARTITION_EXTENDED              0x05
#define PARTITION_HUGE                  0x06
#define PARTITION_IFS                   0x07
#define PARTITION_OS2BOOTMGR            0x0A
#define PARTITION_FAT32                 0x0B
#define PARTITION_FAT32_XINT13          0x0C
#define PARTITION_XINT13                0x0E
#define PARTITION_XINT13_EXTENDED       0x0F
#define PARTITION_MSFT_RECOVERY         0x27
#define PARTITION_MAIN_OS               0x28
#define PARTIITON_OS_DATA               0x29
#define PARTITION_PRE_INSTALLED         0x2a
#define PARTITION_BSP                   0x2b
#define PARTITION_DPP                   0x2c
#define PARTITION_WINDOWS_SYSTEM        0x2d
#define PARTITION_PREP                  0x41
#define PARTITION_LDM                   0x42
#define PARTITION_DM                    0x54
#define PARTITION_EZDRIVE               0x55
#define PARTITION_UNIX                  0x63
#define PARTITION_SPACES_DATA           0xD7
#define PARTITION_SPACES                0xE7
#define PARTITION_GPT                   0xEE
#define PARTITION_SYSTEM                0xEF

#define VALID_NTFT                      0xC0
#define PARTITION_NTFT                  0x80

#ifdef __REACTOS__
#define PARTITION_OLD_LINUX             0x43
#define PARTITION_LINUX                 0x83
#define PARTITION_ISO9660               0x96
#define PARTITION_FREEBSD               0xA5
#define PARTITION_OPENBSD               0xA6
#define PARTITION_NETBSD                0xA9
#endif

/*
 * NOTE: Support for partition types removed from IsFTPartition() and
 * IsRecognizedPartition() because they conflict with 3rd-party types:
 * PARTITION_NTFT | PARTITION_FAT_12 : Conflict with 0x81 "Linux or MINIX"
 * PARTITION_NTFT | PARTITION_FAT_16 : Conflict with 0x84 "Hibernation"
 * PARTITION_NTFT | PARTITION_XINT13 : Conflict with 0x8E "Linux LVM"
 */
#define IsFTPartition(PartitionType) \
  ( ((PartitionType) & PARTITION_NTFT) && ((((PartitionType) & ~VALID_NTFT) == PARTITION_HUGE)  || \
                                           (((PartitionType) & ~VALID_NTFT) == PARTITION_IFS)   || \
                                           (((PartitionType) & ~VALID_NTFT) == PARTITION_FAT32) || \
                                           (((PartitionType) & ~VALID_NTFT) == PARTITION_FAT32_XINT13)) )

#define IsContainerPartition(PartitionType) \
  ( ((PartitionType) == PARTITION_EXTENDED) || \
    ((PartitionType) == PARTITION_XINT13_EXTENDED) )

#ifdef __REACTOS__
#define IsRecognizedPartition(PartitionType) \
  ( IsFTPartition(PartitionType) || \
    ((PartitionType) == PARTITION_FAT_12) || \
    ((PartitionType) == PARTITION_FAT_16) || \
    ((PartitionType) == PARTITION_HUGE)   || \
    ((PartitionType) == PARTITION_IFS)    || \
    ((PartitionType) == PARTITION_FAT32)  || \
    ((PartitionType) == PARTITION_FAT32_XINT13) || \
    ((PartitionType) == PARTITION_XINT13) || \
    ((PartitionType) == PARTITION_LINUX)  || \
    ((PartitionType) == PARTITION_OLD_LINUX) || \
    ((PartitionType) == PARTITION_ISO9660) || \
    ((PartitionType) == PARTITION_FREEBSD) || \
    ((PartitionType) == PARTITION_OPENBSD) || \
    ((PartitionType) == PARTITION_NETBSD) )
#else
#define IsRecognizedPartition(PartitionType) \
  ( IsFTPartition(PartitionType) || \
    ((PartitionType) == PARTITION_FAT_12) || \
    ((PartitionType) == PARTITION_FAT_16) || \
    ((PartitionType) == PARTITION_HUGE)   || \
    ((PartitionType) == PARTITION_IFS)    || \
    ((PartitionType) == PARTITION_FAT32)  || \
    ((PartitionType) == PARTITION_FAT32_XINT13) || \
    ((PartitionType) == PARTITION_XINT13) )
#endif


#define DISK_LOGGING_START   0
#define DISK_LOGGING_STOP    1
#define DISK_LOGGING_DUMP    2
#define DISK_BINNING         3
typedef WORD BAD_TRACK_NUMBER, *PBAD_TRACK_NUMBER;
typedef enum _BIN_TYPES {
    RequestSize,
    RequestLocation
} BIN_TYPES;
typedef struct _BIN_RANGE {
    LARGE_INTEGER StartValue;
    LARGE_INTEGER Length;
} BIN_RANGE, *PBIN_RANGE;
typedef struct _BIN_COUNT {
    BIN_RANGE BinRange;
    DWORD BinCount;
} BIN_COUNT, *PBIN_COUNT;
typedef struct _BIN_RESULTS {
    DWORD NumberOfBins;
    BIN_COUNT BinCounts[1];
} BIN_RESULTS, *PBIN_RESULTS;

typedef enum _MEDIA_TYPE {
  Unknown,
  F5_1Pt2_512,
  F3_1Pt44_512,
  F3_2Pt88_512,
  F3_20Pt8_512,
  F3_720_512,
  F5_360_512,
  F5_320_512,
  F5_320_1024,
  F5_180_512,
  F5_160_512,
  RemovableMedia,
  FixedMedia,
  F3_120M_512,
  F3_640_512,
  F5_640_512,
  F5_720_512,
  F3_1Pt2_512,
  F3_1Pt23_1024,
  F5_1Pt23_1024,
  F3_128Mb_512,
  F3_230Mb_512,
  F8_256_128,
  F3_200Mb_512,
  F3_240M_512,
  F3_32M_512
} MEDIA_TYPE, *PMEDIA_TYPE;

typedef struct _DISK_GEOMETRY {
  LARGE_INTEGER Cylinders;
  MEDIA_TYPE MediaType;
  DWORD TracksPerCylinder;
  DWORD SectorsPerTrack;
  DWORD BytesPerSector;
} DISK_GEOMETRY, *PDISK_GEOMETRY;
typedef struct _PARTITION_INFORMATION {
  LARGE_INTEGER StartingOffset;
  LARGE_INTEGER PartitionLength;
  DWORD HiddenSectors;
  DWORD PartitionNumber;
  BYTE PartitionType;
  BOOLEAN BootIndicator;
  BOOLEAN RecognizedPartition;
  BOOLEAN RewritePartition;
} PARTITION_INFORMATION, *PPARTITION_INFORMATION;
typedef struct _DRIVE_LAYOUT_INFORMATION {
  DWORD PartitionCount;
  DWORD Signature;
  PARTITION_INFORMATION PartitionEntry[1];
} DRIVE_LAYOUT_INFORMATION, *PDRIVE_LAYOUT_INFORMATION;
typedef struct _SET_PARTITION_INFORMATION {
  BYTE PartitionType;
} SET_PARTITION_INFORMATION, *PSET_PARTITION_INFORMATION;

#if (_WIN32_WINNT >= 0x0500)
/* Actually it should be > 0x0500, since this is not present in Windows 2000;
 * however we keep >= 0x0500 for compatibility with MS PSDK. */

typedef enum _PARTITION_STYLE {
  PARTITION_STYLE_MBR,
  PARTITION_STYLE_GPT,
  PARTITION_STYLE_RAW
} PARTITION_STYLE;

typedef struct _CREATE_DISK_GPT {
  GUID DiskId;
  DWORD MaxPartitionCount;
} CREATE_DISK_GPT, *PCREATE_DISK_GPT;
typedef struct _CREATE_DISK_MBR {
  DWORD Signature;
} CREATE_DISK_MBR, *PCREATE_DISK_MBR;
typedef struct _CREATE_DISK {
  PARTITION_STYLE PartitionStyle;
  _ANONYMOUS_UNION union {
    CREATE_DISK_MBR Mbr;
    CREATE_DISK_GPT Gpt;
  };
} CREATE_DISK, *PCREATE_DISK;

typedef enum _DETECTION_TYPE {
  DetectNone,
  DetectInt13,
  DetectExInt13
} DETECTION_TYPE;
typedef struct _DISK_INT13_INFO {
  WORD DriveSelect;
  DWORD MaxCylinders;
  WORD SectorsPerTrack;
  WORD MaxHeads;
  WORD NumberDrives;
} DISK_INT13_INFO, *PDISK_INT13_INFO;
typedef struct _DISK_EX_INT13_INFO {
  WORD ExBufferSize;
  WORD ExFlags;
  DWORD ExCylinders;
  DWORD ExHeads;
  DWORD ExSectorsPerTrack;
  DWORD64 ExSectorsPerDrive;
  WORD ExSectorSize;
  WORD ExReserved;
} DISK_EX_INT13_INFO, *PDISK_EX_INT13_INFO;
typedef struct _DISK_DETECTION_INFO {
  DWORD SizeOfDetectInfo;
  DETECTION_TYPE DetectionType;
  _ANONYMOUS_UNION union {
    _ANONYMOUS_STRUCT struct {
      DISK_INT13_INFO Int13;
      DISK_EX_INT13_INFO ExInt13;
    };
  };
} DISK_DETECTION_INFO, *PDISK_DETECTION_INFO;
typedef struct _DISK_PARTITION_INFO {
  DWORD SizeOfPartitionInfo;
  PARTITION_STYLE PartitionStyle;
  _ANONYMOUS_UNION union {
    struct {
      DWORD Signature;
      DWORD CheckSum;
    } Mbr;
    struct {
      GUID DiskId;
    } Gpt;
  };
} DISK_PARTITION_INFO, *PDISK_PARTITION_INFO;
typedef struct _DISK_GEOMETRY_EX {
  DISK_GEOMETRY Geometry;
  LARGE_INTEGER DiskSize;
  BYTE Data[1];
} DISK_GEOMETRY_EX, *PDISK_GEOMETRY_EX;

#if (NTDDI_VERSION < NTDDI_WS03)
#define DiskGeometryGetPartition(Geometry) \
   ((PDISK_PARTITION_INFO)((Geometry) + 1))

#define DiskGeometryGetDetect(Geometry)\
 ((PDISK_DETECTION_INFO)(((PBYTE)DiskGeometryGetPartition(Geometry) + \
  DiskGeometryGetPartition(Geometry)->SizeOfPartitionInfo)))
#else
#define DiskGeometryGetPartition(Geometry) \
   ((PDISK_PARTITION_INFO)((Geometry)->Data))

#define DiskGeometryGetDetect(Geometry)\
 ((PDISK_DETECTION_INFO)(((ULONG_PTR)DiskGeometryGetPartition(Geometry) + \
  DiskGeometryGetPartition(Geometry)->SizeOfPartitionInfo)))
#endif

typedef struct _PARTITION_INFORMATION_GPT {
  GUID PartitionType;
  GUID PartitionId;
  DWORD64 Attributes;
  WCHAR Name[36];
} PARTITION_INFORMATION_GPT, *PPARTITION_INFORMATION_GPT;
typedef struct _PARTITION_INFORMATION_MBR {
  BYTE PartitionType;
  BOOLEAN BootIndicator;
  BOOLEAN RecognizedPartition;
  DWORD HiddenSectors;
} PARTITION_INFORMATION_MBR, *PPARTITION_INFORMATION_MBR;
typedef struct _PARTITION_INFORMATION_EX {
  PARTITION_STYLE PartitionStyle;
  LARGE_INTEGER StartingOffset;
  LARGE_INTEGER PartitionLength;
  DWORD PartitionNumber;
  BOOLEAN RewritePartition;
#if (NTDDI_VERSION >= NTDDI_WIN10_RS3)
  BOOLEAN  IsServicePartition;
#endif
  _ANONYMOUS_UNION union {
    PARTITION_INFORMATION_MBR Mbr;
    PARTITION_INFORMATION_GPT Gpt;
  };
} PARTITION_INFORMATION_EX, *PPARTITION_INFORMATION_EX;

typedef struct _DRIVE_LAYOUT_INFORMATION_GPT {
  GUID DiskId;
  LARGE_INTEGER StartingUsableOffset;
  LARGE_INTEGER UsableLength;
  DWORD MaxPartitionCount;
} DRIVE_LAYOUT_INFORMATION_GPT, *PDRIVE_LAYOUT_INFORMATION_GPT;
typedef struct _DRIVE_LAYOUT_INFORMATION_MBR {
  DWORD Signature;
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
  DWORD CheckSum;
#endif
} DRIVE_LAYOUT_INFORMATION_MBR, *PDRIVE_LAYOUT_INFORMATION_MBR;
typedef struct _DRIVE_LAYOUT_INFORMATION_EX {
  DWORD PartitionStyle;
  DWORD PartitionCount;
  _ANONYMOUS_UNION union {
    DRIVE_LAYOUT_INFORMATION_MBR Mbr;
    DRIVE_LAYOUT_INFORMATION_GPT Gpt;
  };
  PARTITION_INFORMATION_EX PartitionEntry[1];
} DRIVE_LAYOUT_INFORMATION_EX, *PDRIVE_LAYOUT_INFORMATION_EX;

typedef SET_PARTITION_INFORMATION SET_PARTITION_INFORMATION_MBR;
typedef PARTITION_INFORMATION_GPT SET_PARTITION_INFORMATION_GPT;

typedef struct _SET_PARTITION_INFORMATION_EX {
  PARTITION_STYLE  PartitionStyle;
  _ANONYMOUS_UNION union {
    SET_PARTITION_INFORMATION_MBR  Mbr;
    SET_PARTITION_INFORMATION_GPT  Gpt;
  } DUMMYUNIONNAME;
} SET_PARTITION_INFORMATION_EX, *PSET_PARTITION_INFORMATION_EX;

#endif // (_WIN32_WINNT >= 0x0500)

typedef struct _DISK_GROW_PARTITION {
  DWORD PartitionNumber;
  LARGE_INTEGER BytesToGrow;
} DISK_GROW_PARTITION, *PDISK_GROW_PARTITION;
typedef enum {
  EqualPriority,
  KeepPrefetchedData,
  KeepReadData
} DISK_CACHE_RETENTION_PRIORITY;
typedef struct _DISK_CACHE_INFORMATION {
  BOOLEAN ParametersSavable;
  BOOLEAN ReadCacheEnabled;
  BOOLEAN WriteCacheEnabled;
  DISK_CACHE_RETENTION_PRIORITY ReadRetentionPriority;
  DISK_CACHE_RETENTION_PRIORITY WriteRetentionPriority;
  WORD DisablePrefetchTransferLength;
  BOOLEAN PrefetchScalar;
  _ANONYMOUS_UNION union {
    struct {
      WORD Minimum;
      WORD Maximum;
      WORD MaximumBlocks;
    } ScalarPrefetch;
    struct {
      WORD Minimum;
      WORD Maximum;
    } BlockPrefetch;
  };
} DISK_CACHE_INFORMATION, *PDISK_CACHE_INFORMATION;

typedef struct _DISK_PERFORMANCE {
    LARGE_INTEGER BytesRead;
    LARGE_INTEGER BytesWritten;
    LARGE_INTEGER ReadTime;
    LARGE_INTEGER WriteTime;
    LARGE_INTEGER IdleTime;
    DWORD ReadCount;
    DWORD WriteCount;
    DWORD QueueDepth;
    DWORD SplitCount;
    LARGE_INTEGER QueryTime;
    DWORD   StorageDeviceNumber;
    WCHAR   StorageManagerName[8];
} DISK_PERFORMANCE, *PDISK_PERFORMANCE;
typedef struct _DISK_RECORD {
  LARGE_INTEGER ByteOffset;
  LARGE_INTEGER StartTime;
  LARGE_INTEGER EndTime;
  PVOID VirtualAddress;
  DWORD NumberOfBytes;
  BYTE DeviceNumber;
  BOOLEAN ReadRequest;
} DISK_RECORD, *PDISK_RECORD;
typedef struct _DISK_LOGGING {
  BYTE Function;
  PVOID BufferAddress;
  DWORD BufferSize;
} DISK_LOGGING, *PDISK_LOGGING;
typedef struct DiskQuotaUserInformation {
  LONGLONG QuotaUsed;
  LONGLONG QuotaThreshold;
  LONGLONG QuotaLimit;
} DISKQUOTA_USER_INFORMATION, *PDISKQUOTA_USER_INFORMATION;

typedef struct _FORMAT_PARAMETERS {
  MEDIA_TYPE MediaType;
  DWORD StartCylinderNumber;
  DWORD EndCylinderNumber;
  DWORD StartHeadNumber;
  DWORD EndHeadNumber;
} FORMAT_PARAMETERS, *PFORMAT_PARAMETERS;
typedef struct _FORMAT_EX_PARAMETERS {
  MEDIA_TYPE MediaType;
  DWORD StartCylinderNumber;
  DWORD EndCylinderNumber;
  DWORD StartHeadNumber;
  DWORD EndHeadNumber;
  WORD FormatGapLength;
  WORD SectorsPerTrack;
  WORD SectorNumber[1];
} FORMAT_EX_PARAMETERS, *PFORMAT_EX_PARAMETERS;

typedef struct _GET_LENGTH_INFORMATION {
  LARGE_INTEGER Length;
} GET_LENGTH_INFORMATION, *PGET_LENGTH_INFORMATION;

#define HIST_NO_OF_BUCKETS               24
#define HISTOGRAM_BUCKET_SIZE            sizeof(HISTOGRAM_BUCKET)
#define DISK_HISTOGRAM_SIZE              sizeof(DISK_HISTOGRAM)

typedef struct _HISTOGRAM_BUCKET {
  DWORD Reads;
  DWORD Writes;
} HISTOGRAM_BUCKET, *PHISTOGRAM_BUCKET;
typedef struct _DISK_HISTOGRAM {
  LARGE_INTEGER DiskSize;
  LARGE_INTEGER Start;
  LARGE_INTEGER End;
  LARGE_INTEGER Average;
  LARGE_INTEGER AverageRead;
  LARGE_INTEGER AverageWrite;
  DWORD Granularity;
  DWORD Size;
  DWORD ReadCount;
  DWORD WriteCount;
  PHISTOGRAM_BUCKET Histogram;
} DISK_HISTOGRAM, *PDISK_HISTOGRAM;

typedef struct _PERF_BIN {
  DWORD NumberOfBins;
  DWORD TypeOfBin;
  BIN_RANGE BinsRanges[1];
} PERF_BIN, *PPERF_BIN;

typedef struct _VERIFY_INFORMATION {
  LARGE_INTEGER StartingOffset;
  DWORD Length;
} VERIFY_INFORMATION, *PVERIFY_INFORMATION;

typedef struct _REASSIGN_BLOCKS {
  WORD Reserved;
  WORD Count;
  DWORD BlockNumber[1];
} REASSIGN_BLOCKS, *PREASSIGN_BLOCKS;

#endif /* _NTDDDISK_H_ */

// #ifndef _NTDDSER_
// #define _NTDDSER_

/* Device GUIDs */
#ifdef DEFINE_GUID

DEFINE_GUID(GUID_DEVINTERFACE_COMPORT, 0x86E0D1E0L, 0x8089,
 0x11D0, 0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73);
DEFINE_GUID(GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, 0x4D36E978L, 0xE325,
 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18);

/* obsolete GUID names */
#define GUID_CLASS_COMPORT          GUID_DEVINTERFACE_COMPORT
#define GUID_SERENUM_BUS_ENUMERATOR GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR

#endif /* DEFINE_GUID */

#define IOCTL_SERIAL_LSRMST_INSERT   CTL_CODE(FILE_DEVICE_SERIAL_PORT,31,METHOD_BUFFERED,FILE_ANY_ACCESS)

#define SERIAL_LSRMST_ESCAPE          0
#define SERIAL_LSRMST_LSR_DATA        1
#define SERIAL_LSRMST_LSR_NODATA      2
#define SERIAL_LSRMST_MST             3

// #endif /* _NTDDSER_ */

// #ifndef _NTDDVOL_
// #define _NTDDVOL_

#define IOCTL_VOLUME_BASE ((DWORD)'V')

#if (NTDDI_VERSION >= NTDDI_WIN2K)
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _DISK_EXTENT {
  DWORD DiskNumber;
  LARGE_INTEGER StartingOffset;
  LARGE_INTEGER ExtentLength;
} DISK_EXTENT, *PDISK_EXTENT;
typedef struct _VOLUME_DISK_EXTENTS {
  DWORD NumberOfDiskExtents;
  DISK_EXTENT Extents[1];
} VOLUME_DISK_EXTENTS, *PVOLUME_DISK_EXTENTS;

#define IOCTL_VOLUME_ONLINE  CTL_CODE(IOCTL_VOLUME_BASE, 2, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_VOLUME_OFFLINE CTL_CODE(IOCTL_VOLUME_BASE, 3, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */

#if (NTDDI_VERSION >= NTDDI_WINXP)
#define IOCTL_VOLUME_IS_CLUSTERED \
  CTL_CODE(IOCTL_VOLUME_BASE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VOLUME_GET_GPT_ATTRIBUTES \
  CTL_CODE(IOCTL_VOLUME_BASE, 14, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _VOLUME_GET_GPT_ATTRIBUTES_INFORMATION {
  DWORDLONG  GptAttributes;
} VOLUME_GET_GPT_ATTRIBUTES_INFORMATION, *PVOLUME_GET_GPT_ATTRIBUTES_INFORMATION;
#endif /* (NTDDI_VERSION >= NTDDI_WINXP) */

// #endif /* _NTDDVOL_ */

#ifndef _FILESYSTEMFSCTL_
#define _FILESYSTEMFSCTL_

#define FSCTL_LOCK_VOLUME            CTL_CODE(FILE_DEVICE_FILE_SYSTEM,6,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_UNLOCK_VOLUME          CTL_CODE(FILE_DEVICE_FILE_SYSTEM,7,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_PIPE_IMPERSONATE       CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_DISMOUNT_VOLUME        CTL_CODE(FILE_DEVICE_FILE_SYSTEM,8,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_MOUNT_DBLS_VOLUME      CTL_CODE(FILE_DEVICE_FILE_SYSTEM,13,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_GET_COMPRESSION        CTL_CODE(FILE_DEVICE_FILE_SYSTEM,15,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_SET_COMPRESSION        CTL_CODE(FILE_DEVICE_FILE_SYSTEM,16,METHOD_BUFFERED,FILE_READ_DATA|FILE_WRITE_DATA)
#define FSCTL_READ_COMPRESSION       CTL_CODE(FILE_DEVICE_FILE_SYSTEM,17,METHOD_NEITHER,FILE_READ_DATA)
#define FSCTL_WRITE_COMPRESSION      CTL_CODE(FILE_DEVICE_FILE_SYSTEM,18,METHOD_NEITHER,FILE_WRITE_DATA)
#define FSCTL_GET_NTFS_VOLUME_DATA   CTL_CODE(FILE_DEVICE_FILE_SYSTEM,25,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_GET_NTFS_FILE_RECORD   CTL_CODE(FILE_DEVICE_FILE_SYSTEM,26,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_GET_VOLUME_BITMAP      CTL_CODE(FILE_DEVICE_FILE_SYSTEM,27,METHOD_NEITHER,FILE_ANY_ACCESS)
#define FSCTL_GET_RETRIEVAL_POINTERS CTL_CODE(FILE_DEVICE_FILE_SYSTEM,28,METHOD_NEITHER,FILE_ANY_ACCESS)
#define FSCTL_MOVE_FILE              CTL_CODE(FILE_DEVICE_FILE_SYSTEM,29,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_GET_REPARSE_POINT      CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_SET_REPARSE_POINT      CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_DELETE_REPARSE_POINT   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_SET_SPARSE             CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

#define FSCTL_MARK_VOLUME_DIRTY CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_FILESYSTEM_GET_STATISTICS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 24, METHOD_BUFFERED, FILE_ANY_ACCESS)

#if (_WIN32_WINNT >= _WIN32_WINNT_NT4)
#define FSCTL_IS_VOLUME_DIRTY CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 30, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif

#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
#define FSCTL_GET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 159, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_SET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
#endif

#if (_WIN32_WINNT >= _WIN32_WINNT_WINBLUE)
#define FSCTL_DUPLICATE_EXTENTS_TO_FILE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 209, METHOD_BUFFERED, FILE_WRITE_DATA)
#endif

#if (_WIN32_WINNT >= _WIN32_WINNT_WIN2K)
#define VOLUME_IS_DIRTY                  (0x00000001)
#define VOLUME_UPGRADE_SCHEDULED         (0x00000002)
#define VOLUME_SESSION_OPEN              (0x00000004)
#endif


typedef struct {
  HANDLE FileHandle;
  LARGE_INTEGER StartingVcn;
  LARGE_INTEGER StartingLcn;
  DWORD ClusterCount;
} MOVE_FILE_DATA, *PMOVE_FILE_DATA;
typedef struct RETRIEVAL_POINTERS_BUFFER {
  DWORD ExtentCount;
  LARGE_INTEGER StartingVcn;
  struct {
    LARGE_INTEGER NextVcn;
    LARGE_INTEGER Lcn;
  } Extents[1];
} RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER;
typedef struct {
  LARGE_INTEGER StartingLcn;
} STARTING_LCN_INPUT_BUFFER, *PSTARTING_LCN_INPUT_BUFFER;
typedef struct {
  LARGE_INTEGER StartingVcn;
} STARTING_VCN_INPUT_BUFFER, *PSTARTING_VCN_INPUT_BUFFER;
typedef struct {
  LARGE_INTEGER StartingLcn;
  LARGE_INTEGER BitmapSize;
  BYTE Buffer[1];
} VOLUME_BITMAP_BUFFER, *PVOLUME_BITMAP_BUFFER;
typedef struct {
  LARGE_INTEGER VolumeSerialNumber;
  LARGE_INTEGER NumberSectors;
  LARGE_INTEGER TotalClusters;
  LARGE_INTEGER FreeClusters;
  LARGE_INTEGER TotalReserved;
  DWORD BytesPerSector;
  DWORD BytesPerCluster;
  DWORD BytesPerFileRecordSegment;
  DWORD ClustersPerFileRecordSegment;
  LARGE_INTEGER MftValidDataLength;
  LARGE_INTEGER MftStartLcn;
  LARGE_INTEGER Mft2StartLcn;
  LARGE_INTEGER MftZoneStart;
  LARGE_INTEGER MftZoneEnd;
} NTFS_VOLUME_DATA_BUFFER, *PNTFS_VOLUME_DATA_BUFFER;
typedef struct {
  ULONG ByteCount;
  USHORT MajorVersion;
  USHORT MinorVersion;
} NTFS_EXTENDED_VOLUME_DATA, *PNTFS_EXTENDED_VOLUME_DATA;
typedef struct {
  LARGE_INTEGER FileReferenceNumber;
} NTFS_FILE_RECORD_INPUT_BUFFER, *PNTFS_FILE_RECORD_INPUT_BUFFER;
typedef struct {
  LARGE_INTEGER FileReferenceNumber;
  ULONG FileRecordLength;
  UCHAR FileRecordBuffer[1];
} NTFS_FILE_RECORD_OUTPUT_BUFFER, *PNTFS_FILE_RECORD_OUTPUT_BUFFER;


typedef struct _FILESYSTEM_STATISTICS {
  USHORT FileSystemType;
  USHORT Version;
  ULONG SizeOfCompleteStructure;
  ULONG UserFileReads;
  ULONG UserFileReadBytes;
  ULONG UserDiskReads;
  ULONG UserFileWrites;
  ULONG UserFileWriteBytes;
  ULONG UserDiskWrites;
  ULONG MetaDataReads;
  ULONG MetaDataReadBytes;
  ULONG MetaDataDiskReads;
  ULONG MetaDataWrites;
  ULONG MetaDataWriteBytes;
  ULONG MetaDataDiskWrites;
} FILESYSTEM_STATISTICS, *PFILESYSTEM_STATISTICS;

#define FILESYSTEM_STATISTICS_TYPE_NTFS     1
#define FILESYSTEM_STATISTICS_TYPE_FAT      2
#define FILESYSTEM_STATISTICS_TYPE_EXFAT    3

typedef struct _FAT_STATISTICS {
  ULONG CreateHits;
  ULONG SuccessfulCreates;
  ULONG FailedCreates;
  ULONG NonCachedReads;
  ULONG NonCachedReadBytes;
  ULONG NonCachedWrites;
  ULONG NonCachedWriteBytes;
  ULONG NonCachedDiskReads;
  ULONG NonCachedDiskWrites;
} FAT_STATISTICS, *PFAT_STATISTICS;

typedef struct _EXFAT_STATISTICS {
  ULONG CreateHits;
  ULONG SuccessfulCreates;
  ULONG FailedCreates;
  ULONG NonCachedReads;
  ULONG NonCachedReadBytes;
  ULONG NonCachedWrites;
  ULONG NonCachedWriteBytes;
  ULONG NonCachedDiskReads;
  ULONG NonCachedDiskWrites;
} EXFAT_STATISTICS, *PEXFAT_STATISTICS;

typedef struct _NTFS_STATISTICS {
  ULONG LogFileFullExceptions;
  ULONG OtherExceptions;
  ULONG MftReads;
  ULONG MftReadBytes;
  ULONG MftWrites;
  ULONG MftWriteBytes;
  struct {
    USHORT Write;
    USHORT Create;
    USHORT SetInfo;
    USHORT Flush;
  } MftWritesUserLevel;
  USHORT MftWritesFlushForLogFileFull;
  USHORT MftWritesLazyWriter;
  USHORT MftWritesUserRequest;
  ULONG Mft2Writes;
  ULONG Mft2WriteBytes;
  struct {
    USHORT Write;
    USHORT Create;
    USHORT SetInfo;
    USHORT Flush;
  } Mft2WritesUserLevel;
  USHORT Mft2WritesFlushForLogFileFull;
  USHORT Mft2WritesLazyWriter;
  USHORT Mft2WritesUserRequest;
  ULONG RootIndexReads;
  ULONG RootIndexReadBytes;
  ULONG RootIndexWrites;
  ULONG RootIndexWriteBytes;
  ULONG BitmapReads;
  ULONG BitmapReadBytes;
  ULONG BitmapWrites;
  ULONG BitmapWriteBytes;
  USHORT BitmapWritesFlushForLogFileFull;
  USHORT BitmapWritesLazyWriter;
  USHORT BitmapWritesUserRequest;
  struct {
    USHORT Write;
    USHORT Create;
    USHORT SetInfo;
  } BitmapWritesUserLevel;
  ULONG MftBitmapReads;
  ULONG MftBitmapReadBytes;
  ULONG MftBitmapWrites;
  ULONG MftBitmapWriteBytes;
  USHORT MftBitmapWritesFlushForLogFileFull;
  USHORT MftBitmapWritesLazyWriter;
  USHORT MftBitmapWritesUserRequest;
  struct {
    USHORT Write;
    USHORT Create;
    USHORT SetInfo;
    USHORT Flush;
  } MftBitmapWritesUserLevel;
  ULONG UserIndexReads;
  ULONG UserIndexReadBytes;
  ULONG UserIndexWrites;
  ULONG UserIndexWriteBytes;
  ULONG LogFileReads;
  ULONG LogFileReadBytes;
  ULONG LogFileWrites;
  ULONG LogFileWriteBytes;
  struct {
    ULONG Calls;
    ULONG Clusters;
    ULONG Hints;
    ULONG RunsReturned;
    ULONG HintsHonored;
    ULONG HintsClusters;
    ULONG Cache;
    ULONG CacheClusters;
    ULONG CacheMiss;
    ULONG CacheMissClusters;
  } Allocate;
} NTFS_STATISTICS, *PNTFS_STATISTICS;

#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER {
  WORD ChecksumAlgorithm;
  WORD Reserved;
  DWORD Flags;
  DWORD ChecksumChunkSizeInBytes;
  DWORD ClusterSizeInBytes;
} FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER;

typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER {
  WORD ChecksumAlgorithm;
  WORD Reserved;
  DWORD Flags;
} FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER;
#endif

#if (_WIN32_WINNT >= _WIN32_WINNT_WINBLUE)
typedef struct _DUPLICATE_EXTENTS_DATA {
    HANDLE FileHandle;
    LARGE_INTEGER SourceFileOffset;
    LARGE_INTEGER TargetFileOffset;
    LARGE_INTEGER ByteCount;
} DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA;
#endif

#endif /* _FILESYSTEMFSCTL_ */


#ifdef _MSC_VER
#pragma warning(pop)
#endif

#ifdef __cplusplus
}
#endif
#endif /* _WINIOCTL_ */
